import 'package:app/index.dart';
import 'package:app/page/ReadBookPage.dart';
import 'package:app/page/add.dart';
import 'package:app/page/countdownView.dart';
import 'package:app/page/updateColor.dart';
import 'package:app/page/updateImgUrl.dart';
import 'package:app/router/routerUtils.dart';
import 'package:flutter/cupertino.dart';

const Type _Home_ = HomePage;
final _Rouers = RouterUtils.typeNameMap({
  HomePage: (_) => HomePage(),
  Add: (_) => Add(),
  CountdownView: (_) => CountdownView(),
  ReadBookPage: (_) => ReadBookPage(),
  UpdateColor:(_)=>UpdateColor(),
  UpdateImgurl:(_)=>UpdateImgurl(),
});

class UserRouter {
  UserRouter._();
  Object? _arguments;
  String? _routerName;
  BuildContext? _context;

  //路由定义
  static final ROUTERS = _Rouers;
  //单例对象
  static final UserRouter _instance = UserRouter._();
  //对外部公开首页的路由名
  static final String INDEX = RouterUtils.typeName(_Home_);
  //重置临时变量
  void _restVariables() {
    _context = null;
    _arguments = null;
    _routerName = null;
  }

  //携带参数跳转
  Future<T?> to<T extends Object?>() {
    assert(_context != null);
    assert(_routerName != null);
    return Navigator.pushNamed<T>(
      _context!,
      _routerName!,
      arguments: _arguments,
      //完成整个流程重置临时变量
    ).whenComplete(_restVariables);
  }

  static UserRouter _withArguments(dynamic arguments) {
    _instance._arguments = arguments;
    return _instance;
  }

  static RT of<RT extends RouterBridge>(BuildContext context) {
    assert(
      RT != RouterBridge<dynamic>,
      "You must specify the route type, for example: of<Page>(context)",
    );
    final name = RouterUtils.typeName(RT);
    assert(_Rouers.containsKey(name), "Route\"$RT\"is not registered.");
    _instance._context = context;
    _instance._routerName = name;
    var builder = _Rouers[name]!;
    return builder.call(context) as RT;
  }

  ///不带任何参数的路由跳转
  static Future<T?> routeTo<T extends Object?>(
    BuildContext context,
    Type router,
  ) {
    final name = RouterUtils.typeName(router); //将传入的Type转换成字符串
    assert(_Rouers.containsKey(name), "Route \"$router\" is not registered.");
    return Navigator.pushNamed<T>(context, name);
  }

  static CupertinoPageRoute onGenerateRoute<T>(RouteSettings settings) {
    final builder = _Rouers[settings.name] ?? _Rouers[INDEX]!;
    return CupertinoPageRoute<T>(builder: builder, settings: settings);
  }
}

mixin RouterBridge<RT_ARG_TYPE> {
  UserRouter arguments(RT_ARG_TYPE args) => UserRouter._withArguments(args);

  RT_ARG_TYPE? argumentsOf(BuildContext context) {
    final Object? arguments = ModalRoute.of(context)?.settings.arguments;
    return arguments == null ? null : arguments as RT_ARG_TYPE;
  }
}
